package mysql

import (
	"go.uber.org/zap"
	"struggle/model"
)

type viewDAO struct{}

var DefaultView = viewDAO{}

func (v viewDAO) Create(view *model.ViewMeta) (err error) {
	// 涉及处理多表，需要使用事务
	tx, err := db.Begin()
	if err != nil {
		zap.L().Error("mysql transaction failed", zap.Error(err))
		return
	}
	defer ClearTransaction(tx) // 如果出现异常情况,导致没有 commit和rollback,可以用来收尾

	// 1. 新增ip访问表
	sqlStr := `INSERT IGNORE INTO st_view (ip, objtype, objid) VALUES (?, ?, ?)`
	_, err = tx.Exec(sqlStr, view.Ip, view.ObjectType, view.ObjectId)
	if err != nil {
		zap.L().Error("viewDAO.Create failed", zap.Any("view", view), zap.Error(err))
		return
	}
	// 3. 获取指定sn的ip数量
	count, err := v.Get(view.ObjectType, view.ObjectId)
	// 2. 如果是访问文章就相应更新 文章扩展表 的浏览数字段
	if view.ObjectType == 0 {
		if err = DefaultArticle.UpdateExView(view.ObjectId, count); err != nil {
			return
		}
	}
	// 3. 如果是访问提问就相应更新 问题扩展表 的浏览数字数
	if view.ObjectType == 1 {
		if err = DefaultQuestion.UpdateExView(view.ObjectId, count); err != nil {
			return
		}
	}
	// 事务提交
	if err := tx.Commit(); err != nil {
		zap.L().Error("commit view failed", zap.Any("view", view), zap.Error(err))
	}
	return
}

// 获取指定类型的指定 ID 的 ip 总数
func (v viewDAO) Get(objType int, objId uint64) (count int, err error) {
	sqlStr := `SELECT count(ip) FROM st_view WHERE objtype = ? AND objid = ?`
	err = db.Get(&count, sqlStr, objType, objId)
	if err != nil {
		zap.L().Error("Get View Count failed", zap.Error(err))
		return
	}
	return
}
